﻿using System;
using System.Collections.Generic;

using Gonte.Reflection;

namespace Gonte
{
    /// <summary>
    /// Tests for objects that are primitives in the business point of view.
    /// That is the smallest building blocks of other objects
    /// </summary>
    public class PrimitiveType
    {
        #region Constructors

        static PrimitiveType()
        {
            primitives_ = new Dictionary<string, Object>(32);

            primitives_.Add(typeof(string).FullName, null);
            primitives_.Add(typeof(int).FullName, null);
            primitives_.Add(typeof(Guid).FullName, null);
            primitives_.Add(typeof(Decimal).FullName, null);
            primitives_.Add(typeof(DateTime).FullName, null);
            primitives_.Add(typeof(bool).FullName, null);
            primitives_.Add(typeof(byte).FullName, null);
            primitives_.Add(typeof(sbyte).FullName, null);
            primitives_.Add(typeof(short).FullName, null);
            primitives_.Add(typeof(ushort).FullName, null);
            primitives_.Add(typeof(uint).FullName, null);
            primitives_.Add(typeof(long).FullName, null);
            primitives_.Add(typeof(ulong).FullName, null);
            primitives_.Add(typeof(float).FullName, null);
            primitives_.Add(typeof(double).FullName, null);
            primitives_.Add(typeof(char).FullName, null);
            // Add new primitive types here
        } 

        #endregion

        #region Methods

        public static bool IsPrimitive(Object @object)
        {
            return IsPrimitive(@object.GetType());
        }

        public static bool IsPrimitive(Type type)
        {
            if (TypeHelper.IsNullable(type)) // Unbox the nullable property
            {
                type = type.GetGenericArguments()[0];
            }

            return (type.IsEnum
                    || IsPrimitive(type.FullName));
        }

        public static bool IsPrimitive(string typeName)
        {
            return primitives_.ContainsKey(typeName);
        }

        #endregion

        #region Fields

        private static readonly Dictionary<string, Object> primitives_; 

        #endregion
    }
}
